// Copyright 2022-2023 Bloomberg Finance L.P.
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// mwcex_promise_cpp03.h                                              -*-C++-*-

// Automatically generated file.  **DO NOT EDIT**

#ifndef INCLUDED_MWCEX_PROMISE_CPP03
#define INCLUDED_MWCEX_PROMISE_CPP03

//@PURPOSE: Provide C++03 implementation for mwcex_promise.h
//
//@CLASSES: See mwcex_promise.h for list of classes
//
//@SEE_ALSO: mwcex_promise
//
//@DESCRIPTION:  This component is the C++03 translation of a C++11 component,
// generated by the 'sim_cpp11_features.pl' program.  If the original header
// contains any specially delimited regions of C++11 code, then this generated
// file contains the C++03 equivalent, i.e., with variadic templates expanded
// and rvalue-references replaced by 'bslmf::MovableRef' objects.  The header
// code in this file is designed to be '#include'd into the original header
// when compiling with a C++03 compiler.  If there are no specially delimited
// regions of C++11 code, then this header contains no code and is not
// '#include'd in the original header.
//
// Generated on Wed Jun 29 04:19:38 2022
// Command line: sim_cpp11_features.pl mwcex_promise.h

#ifdef COMPILING_MWCEX_PROMISE_H

namespace BloombergLP {

// FORWARD DECLARATION
namespace bslma {
class Allocator;
}

namespace mwcex {

// =============
// class Promise
// =============

template <class R>
class Promise {
    // Provides a mechanism to store a value or an exception that is later
    // acquired asynchronously via a 'mwcex::Future' object created by the
    // 'mwcex::Promise' object.
    //
    // 'R' must meet the requirements of Destructible as specified in the C++
    // standard.

  private:
    // PRIVATE TYPES
    typedef typename Future<R>::SharedStateType SharedStateType;

  private:
    // PRIVATE DATA
    bsl::shared_ptr<SharedStateType> d_sharedState;

    // FRIENDS
    template <class>
    friend class Promise;

  private:
    // NOT IMPLEMENTED
    Promise(const Promise&) BSLS_KEYWORD_DELETED;
    Promise& operator=(const Promise&) BSLS_KEYWORD_DELETED;

  public:
    // CREATORS
    explicit Promise(bslma::Allocator* basicAllocator = 0);
    // Create a 'Promise' object holding a shared state of type
    // 'mwcex::Future<R>::SharedStateType' initialized with the specified
    // 'basicAllocator'.

    explicit Promise(bsls::SystemClockType::Enum clockType,
                     bslma::Allocator*           basicAllocator = 0);
    // Create a 'Promise' object holding a shared state of type
    // 'mwcex::Future<R>::SharedStateType' initialized with the specified
    // 'clockType' and 'basicAllocator'.

    Promise(bslmf::MovableRef<Promise> original) BSLS_KEYWORD_NOEXCEPT;
    // Create a 'Promise' object that refers to and assumes management of
    // the same shared state (if any) as the specified 'original' object,
    // and leave 'original' having no shared state.

    ~Promise();
    // Destroy this object. If '*this' has a shared state and the shared
    // state is not ready, store a 'mwcex::PromiseBroken' exception object
    // into the shared state and make the state ready, then release the
    // underlying shared state.

  public:
    // MANIPULATORS
    Promise& operator=(bslmf::MovableRef<Promise> rhs) BSLS_KEYWORD_NOEXCEPT;
    // Make this promise refer to and assume management of the same shared
    // state (if any) as the specified 'rhs' promise, and leave 'rhs'
    // having no shared state. Return '*this'.

    void setValue(const R& value);
    // Atomically store the specified 'value' into the shared state as if
    // by direct-non-list-initializing an object of type 'R' with 'value'
    // and make the state ready. If a callback is attached to the shared
    // state, invoke, and then destroy it. Effectively calls 'setValue'
    // on the underlying shared state. The behavior is undefined if the
    // shared state is ready or if the promise has no shared state.
    //
    // Throws any exception thrown by the selected constructor of 'R', or
    // any exception thrown by the attached callback. If an exception is
    // thrown by 'R's constructor, this function has no effect. If an
    // exception is thrown by the attached callback, the stored value stays
    // initialized and the callback is destroyed.
    //
    // 'R' must meet the requirements of CopyConstructible as specified in
    // the C++ standard.

    void setValue(bslmf::MovableRef<R> value);
    // Atomically store the specified 'value' into the shared state as if
    // by direct-non-list-initializing an object of type 'R' with
    // 'bsl::move(value)' and make the state ready. If a callback is
    // attached to the shared state, invoke, and then destroy it.
    // Effectively calls 'setValue' on the underlying shared state. The
    // behavior is undefined if the shared state is ready or if the promise
    // has no shared state.
    //
    // Throws any exception thrown by the selected constructor of 'R', or
    // any exception thrown by the attached callback. If an exception is
    // thrown by 'R's constructor, this function has no effect. If an
    // exception is thrown by the attached callback, the stored value stays
    // initialized and the callback is destroyed.
    //
    // 'R' must meet the requirements of MoveConstructible as specified in
    // the C++ standard.

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl mwcex_promise.h
#ifndef MWCEX_PROMISE_VARIADIC_LIMIT
#define MWCEX_PROMISE_VARIADIC_LIMIT 9
#endif
#ifndef MWCEX_PROMISE_VARIADIC_LIMIT_A
#define MWCEX_PROMISE_VARIADIC_LIMIT_A MWCEX_PROMISE_VARIADIC_LIMIT
#endif
#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 0
    void emplaceValue();
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 0

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 1
    template <class ARGS_1>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 1

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 2
    template <class ARGS_1, class ARGS_2>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 2

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 3
    template <class ARGS_1, class ARGS_2, class ARGS_3>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 3

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 4
    template <class ARGS_1, class ARGS_2, class ARGS_3, class ARGS_4>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 4

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 5
    template <class ARGS_1,
              class ARGS_2,
              class ARGS_3,
              class ARGS_4,
              class ARGS_5>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 5

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 6
    template <class ARGS_1,
              class ARGS_2,
              class ARGS_3,
              class ARGS_4,
              class ARGS_5,
              class ARGS_6>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_6) args_6);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 6

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 7
    template <class ARGS_1,
              class ARGS_2,
              class ARGS_3,
              class ARGS_4,
              class ARGS_5,
              class ARGS_6,
              class ARGS_7>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_6) args_6,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_7) args_7);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 7

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 8
    template <class ARGS_1,
              class ARGS_2,
              class ARGS_3,
              class ARGS_4,
              class ARGS_5,
              class ARGS_6,
              class ARGS_7,
              class ARGS_8>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_6) args_6,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_7) args_7,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_8) args_8);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 8

#if MWCEX_PROMISE_VARIADIC_LIMIT_A >= 9
    template <class ARGS_1,
              class ARGS_2,
              class ARGS_3,
              class ARGS_4,
              class ARGS_5,
              class ARGS_6,
              class ARGS_7,
              class ARGS_8,
              class ARGS_9>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_6) args_6,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_7) args_7,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_8) args_8,
                      BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_9) args_9);
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_A >= 9

#else
    // The generated code below is a workaround for the absence of perfect
    // forwarding in some compilers.
    template <class... ARGS>
    void emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
// }}} END GENERATED CODE
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_EXCEPTION_HANDLING
    void setException(bsl::exception_ptr exception);
    // Atomically store the specified 'exception' pointer into the shared
    // state and make the state ready. If a callback is attached to the
    // shared state, invoke, and then destroy it. Effectively calls
    // 'setException' on the underlying shared state. The behavior is
    // undefined if the shared state is ready or if the promise has no
    // shared state.
    //
    // Throws any exception thrown by the attached callback. If an
    // exception is thrown, the stored exception stays initialized and the
    // callback is destroyed.
#endif

    template <class EXCEPTION>
    void setException(BSLS_COMPILERFEATURES_FORWARD_REF(EXCEPTION) exception);
    // Atomically store the specified 'exception' object into the shared
    // state as if by direct-non-list-initializing an object of type
    // 'bsl::decay_t<EXCEPTION>' with 'bsl::forward<EXCEPTION>(EXCEPTION)'
    // and make the state ready. If a callback is attached to the shared
    // state, invoke, and then destroy it. Effectively calls
    // 'setException' on the underlying shared state. The behavior is
    // undefined if the shared state is ready or if the promise has no
    // shared state.
    //
    // Throws any exception thrown by the selected constructor of
    // 'bsl::decay_t<EXCEPTION>', any exception thrown by the attached
    // callback, or 'bsl::bad_alloc' if memory allocation fails. If an
    // exception is thrown by 'bsl::decay_t<EXCEPTION>'s constructor or due
    // to memory allocation failure, this function has no effect. If an
    // exception is thrown by the attached callback, the stored exception
    // stays initialized and the callback is destroyed.
    //
    // 'bsl::decay_t<EXCEPTION>' must meet the requirements of Destructible
    // and CopyConstructible as specified in the C++ standard.

    void swap(Promise& other) BSLS_KEYWORD_NOEXCEPT;
    // Swap the contents of '*this' and 'other'.

  public:
    // ACCESSORS
    Future<R> future() const BSLS_KEYWORD_NOEXCEPT;
    // Return a future associated with the shared state owned by '*this'.
    // The behavior is undefined unless the promise has a shared state.

  public:
    // TRAITS
    BSLMF_NESTED_TRAIT_DECLARATION(Promise, bslma::UsesBslmaAllocator)
    BSLMF_NESTED_TRAIT_DECLARATION(Promise, bslmf::IsBitwiseMoveable)
};

// ===================
// class Promise<void>
// ===================

template <>
class Promise<void> : private Promise<bslmf::Nil> {
    // Provides a specialization of 'Promise' for 'void' result type.

  private:
    // PRIVATE TYPES
    typedef Promise<bslmf::Nil> Impl;

  private:
    // NOT IMPLEMENTED
    Promise(const Promise&) BSLS_KEYWORD_DELETED;
    Promise& operator=(const Promise&) BSLS_KEYWORD_DELETED;

  public:
    // CREATORS
    explicit Promise(bslma::Allocator* basicAllocator = 0);
    // Same as for the non-specialized class template.

    explicit Promise(bsls::SystemClockType::Enum clockType,
                     bslma::Allocator*           basicAllocator = 0);
    // Same as for the non-specialized class template.

    Promise(bslmf::MovableRef<Promise> original) BSLS_KEYWORD_NOEXCEPT;
    // Same as for the non-specialized class template.

    //! ~Promise();
    // Same as for the non-specialized class template.

  public:
    // MANIPULATORS
    Promise& operator=(bslmf::MovableRef<Promise> rhs) BSLS_KEYWORD_NOEXCEPT;
    // Same as for the non-specialized class template.

    void setValue();
    // Atomically make the shared state ready. If a callback is attached to
    // the shared state, invoke, and then destroy it. Effectively calls
    // 'setValue' on the underlying shared state. The behavior is
    // undefined if the shared state is ready or if the promise has no
    // shared state.
    //
    // Throws any exception thrown by the attached callback. If an
    // exception is thrown, the stored value stays initialized and the
    // callback is destroyed.

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_EXCEPTION_HANDLING
    void setException(bsl::exception_ptr exception);
    // Same as for the non-specialized class template.
#endif

    template <class EXCEPTION>
    void setException(BSLS_COMPILERFEATURES_FORWARD_REF(EXCEPTION) exception);
    // Same as for the non-specialized class template.

    void swap(Promise& other) BSLS_KEYWORD_NOEXCEPT;
    // Same as for the non-specialized class template.

  public:
    // ACCESSORS
    Future<void> future() const BSLS_KEYWORD_NOEXCEPT;
    // Same as for the non-specialized class template.

  public:
    // TRAITS
    BSLMF_NESTED_TRAIT_DECLARATION(Promise, bslma::UsesBslmaAllocator)
    BSLMF_NESTED_TRAIT_DECLARATION(Promise, bslmf::IsBitwiseMoveable)
};

// =================
// class Promise<R&>
// =================

template <class R>
class Promise<R&> : private Promise<bsl::reference_wrapper<R> > {
    // Provides a specialization of 'Promise' for reference result types.

  private:
    // PRIVATE TYPES
    typedef Promise<bsl::reference_wrapper<R> > Impl;

  private:
    // NOT IMPLEMENTED
    Promise(const Promise&) BSLS_KEYWORD_DELETED;
    Promise& operator=(const Promise&) BSLS_KEYWORD_DELETED;

  public:
    // CREATORS
    explicit Promise(bslma::Allocator* basicAllocator = 0);
    // Same as for the non-specialized class template.

    explicit Promise(bsls::SystemClockType::Enum clockType,
                     bslma::Allocator*           basicAllocator = 0);
    // Same as for the non-specialized class template.

    Promise(bslmf::MovableRef<Promise> original) BSLS_KEYWORD_NOEXCEPT;
    // Same as for the non-specialized class template.

    //! ~Promise();
    // Same as for the non-specialized class template.

  public:
    // MANIPULATORS
    Promise& operator=(bslmf::MovableRef<Promise> rhs) BSLS_KEYWORD_NOEXCEPT;
    // Same as for the non-specialized class template.

    void setValue(R& value);
    // Atomically store the specified 'value' reference into the shared
    // state and make the state ready. If a callback is attached to the
    // shared state, invoke, and then destroy it. Effectively calls
    // 'setValue' on the underlying shared state. The behavior is
    // undefined if the shared state is ready or if the promise has no
    // shared state.
    //
    // Throws any exception thrown by the attached callback. If an
    // exception is thrown, the stored reference stays initialized and the
    // callback is destroyed.

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_EXCEPTION_HANDLING
    void setException(bsl::exception_ptr exception);
    // Same as for the non-specialized class template.
#endif

    template <class EXCEPTION>
    void setException(BSLS_COMPILERFEATURES_FORWARD_REF(EXCEPTION) exception);
    // Same as for the non-specialized class template.

    void swap(Promise& other) BSLS_KEYWORD_NOEXCEPT;
    // Same as for the non-specialized class template.

  public:
    // ACCESSORS
    Future<R&> future() const BSLS_KEYWORD_NOEXCEPT;
    // Same as for the non-specialized class template.

  public:
    // TRAITS
    BSLMF_NESTED_TRAIT_DECLARATION(Promise, bslma::UsesBslmaAllocator)
    BSLMF_NESTED_TRAIT_DECLARATION(Promise, bslmf::IsBitwiseMoveable)
};

// ===================
// class PromiseBroken
// ===================

class PromiseBroken : public bsl::exception {
    // Provide an exception class to indicate a promise was broken.

  public:
    // CREATORS
    PromiseBroken() BSLS_KEYWORD_NOEXCEPT;
    // Create a 'PromiseBroken' object.

  public:
    // ACCESSORS
    const char* what() const BSLS_EXCEPTION_WHAT_NOTHROW BSLS_KEYWORD_OVERRIDE;
    // Return a pointer to the string literal "PromiseBroken", with a
    // storage duration of the lifetime of the program.
};

// FREE OPERATORS
template <class R>
void swap(Promise<R>& lhs, Promise<R>& rhs) BSLS_KEYWORD_NOEXCEPT;
// Swap the contents of 'lhs' and 'rhs'.

// ============================================================================
//                           INLINE DEFINITIONS
// ============================================================================

// -------------
// class Promise
// -------------

// CREATORS
template <class R>
inline Promise<R>::Promise(bslma::Allocator* basicAllocator)
: d_sharedState(bsl::allocate_shared<SharedStateType>(basicAllocator))
{
    // NOTHING
}

template <class R>
inline Promise<R>::Promise(bsls::SystemClockType::Enum clockType,
                           bslma::Allocator*           basicAllocator)
: d_sharedState(
      bsl::allocate_shared<SharedStateType>(basicAllocator, clockType))
{
    // NOTHING
}

template <class R>
inline Promise<R>::Promise(bslmf::MovableRef<Promise> original)
    BSLS_KEYWORD_NOEXCEPT
: d_sharedState(bslmf::MovableRefUtil::move(
      bslmf::MovableRefUtil::access(original).d_sharedState))
{
    // NOTHING
}

template <class R>
inline Promise<R>::~Promise()
{
    if (d_sharedState && !d_sharedState->isReady()) {
        // The shared state is not ready. Store a 'PromiseBroken' exception.
        d_sharedState->setException(PromiseBroken());
    }
}

// MANIPULATORS
template <class R>
inline Promise<R>&
Promise<R>::operator=(bslmf::MovableRef<Promise> rhs) BSLS_KEYWORD_NOEXCEPT
{
    d_sharedState = bslmf::MovableRefUtil::move(
        bslmf::MovableRefUtil::access(rhs).d_sharedState);
    return *this;
}

template <class R>
inline void Promise<R>::setValue(const R& value)
{
    // PRECONDITIONS
    BSLS_ASSERT(d_sharedState);

    d_sharedState->setValue(value);
}

template <class R>
inline void Promise<R>::setValue(bslmf::MovableRef<R> value)
{
    // PRECONDITIONS
    BSLS_ASSERT(d_sharedState);

    d_sharedState->setValue(bslmf::MovableRefUtil::move(value));
}

#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
// {{{ BEGIN GENERATED CODE
// Command line: sim_cpp11_features.pl mwcex_promise.h
#ifndef MWCEX_PROMISE_VARIADIC_LIMIT
#define MWCEX_PROMISE_VARIADIC_LIMIT 9
#endif
#ifndef MWCEX_PROMISE_VARIADIC_LIMIT_B
#define MWCEX_PROMISE_VARIADIC_LIMIT_B MWCEX_PROMISE_VARIADIC_LIMIT
#endif
#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 0
template <class R>
inline void Promise<R>::emplaceValue()
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue();
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 0

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 1
template <class R>
template <class ARGS_1>
inline void Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1)
                                         args_1)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 1

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 2
template <class R>
template <class ARGS_1, class ARGS_2>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1),
                                bslmf::Util::forward<ARGS_2>(args_2));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 2

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 3
template <class R>
template <class ARGS_1, class ARGS_2, class ARGS_3>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1),
                                bslmf::Util::forward<ARGS_2>(args_2),
                                bslmf::Util::forward<ARGS_3>(args_3));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 3

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 4
template <class R>
template <class ARGS_1, class ARGS_2, class ARGS_3, class ARGS_4>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1),
                                bslmf::Util::forward<ARGS_2>(args_2),
                                bslmf::Util::forward<ARGS_3>(args_3),
                                bslmf::Util::forward<ARGS_4>(args_4));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 4

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 5
template <class R>
template <class ARGS_1, class ARGS_2, class ARGS_3, class ARGS_4, class ARGS_5>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1),
                                bslmf::Util::forward<ARGS_2>(args_2),
                                bslmf::Util::forward<ARGS_3>(args_3),
                                bslmf::Util::forward<ARGS_4>(args_4),
                                bslmf::Util::forward<ARGS_5>(args_5));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 5

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 6
template <class R>
template <class ARGS_1,
          class ARGS_2,
          class ARGS_3,
          class ARGS_4,
          class ARGS_5,
          class ARGS_6>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_6) args_6)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1),
                                bslmf::Util::forward<ARGS_2>(args_2),
                                bslmf::Util::forward<ARGS_3>(args_3),
                                bslmf::Util::forward<ARGS_4>(args_4),
                                bslmf::Util::forward<ARGS_5>(args_5),
                                bslmf::Util::forward<ARGS_6>(args_6));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 6

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 7
template <class R>
template <class ARGS_1,
          class ARGS_2,
          class ARGS_3,
          class ARGS_4,
          class ARGS_5,
          class ARGS_6,
          class ARGS_7>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_6) args_6,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_7) args_7)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1),
                                bslmf::Util::forward<ARGS_2>(args_2),
                                bslmf::Util::forward<ARGS_3>(args_3),
                                bslmf::Util::forward<ARGS_4>(args_4),
                                bslmf::Util::forward<ARGS_5>(args_5),
                                bslmf::Util::forward<ARGS_6>(args_6),
                                bslmf::Util::forward<ARGS_7>(args_7));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 7

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 8
template <class R>
template <class ARGS_1,
          class ARGS_2,
          class ARGS_3,
          class ARGS_4,
          class ARGS_5,
          class ARGS_6,
          class ARGS_7,
          class ARGS_8>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_6) args_6,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_7) args_7,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_8) args_8)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1),
                                bslmf::Util::forward<ARGS_2>(args_2),
                                bslmf::Util::forward<ARGS_3>(args_3),
                                bslmf::Util::forward<ARGS_4>(args_4),
                                bslmf::Util::forward<ARGS_5>(args_5),
                                bslmf::Util::forward<ARGS_6>(args_6),
                                bslmf::Util::forward<ARGS_7>(args_7),
                                bslmf::Util::forward<ARGS_8>(args_8));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 8

#if MWCEX_PROMISE_VARIADIC_LIMIT_B >= 9
template <class R>
template <class ARGS_1,
          class ARGS_2,
          class ARGS_3,
          class ARGS_4,
          class ARGS_5,
          class ARGS_6,
          class ARGS_7,
          class ARGS_8,
          class ARGS_9>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_1) args_1,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_2) args_2,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_3) args_3,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_4) args_4,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_5) args_5,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_6) args_6,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_7) args_7,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_8) args_8,
                         BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_9) args_9)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS_1>(args_1),
                                bslmf::Util::forward<ARGS_2>(args_2),
                                bslmf::Util::forward<ARGS_3>(args_3),
                                bslmf::Util::forward<ARGS_4>(args_4),
                                bslmf::Util::forward<ARGS_5>(args_5),
                                bslmf::Util::forward<ARGS_6>(args_6),
                                bslmf::Util::forward<ARGS_7>(args_7),
                                bslmf::Util::forward<ARGS_8>(args_8),
                                bslmf::Util::forward<ARGS_9>(args_9));
}
#endif  // MWCEX_PROMISE_VARIADIC_LIMIT_B >= 9

#else
// The generated code below is a workaround for the absence of perfect
// forwarding in some compilers.
template <class R>
template <class... ARGS>
inline void
Promise<R>::emplaceValue(BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args)
{
    BSLS_ASSERT(d_sharedState);

    d_sharedState->emplaceValue(bslmf::Util::forward<ARGS>(args)...);
}
// }}} END GENERATED CODE
#endif

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_EXCEPTION_HANDLING
template <class R>
inline void Promise<R>::setException(bsl::exception_ptr exception)
{
    // PRECONDITIONS
    BSLS_ASSERT(d_sharedState);

    d_sharedState->setException(exception);
}
#endif

template <class R>
template <class EXCEPTION>
inline void
Promise<R>::setException(BSLS_COMPILERFEATURES_FORWARD_REF(EXCEPTION)
                             exception)
{
    // PRECONDITIONS
    BSLS_ASSERT(d_sharedState);

    d_sharedState->setException(
        BSLS_COMPILERFEATURES_FORWARD(EXCEPTION, exception));
}

template <class R>
inline void Promise<R>::swap(Promise& other) BSLS_KEYWORD_NOEXCEPT
{
    d_sharedState.swap(other.d_sharedState);
}

// ACCESSORS
template <class R>
inline Future<R> Promise<R>::future() const BSLS_KEYWORD_NOEXCEPT
{
    // PRECONDITIONS
    BSLS_ASSERT(d_sharedState);

    return Future<R>(d_sharedState);
}

// -------------------
// class Promise<void>
// -------------------

// CREATORS
inline Promise<void>::Promise(bslma::Allocator* basicAllocator)
: Impl(basicAllocator)
{
    // NOTHING
}

inline Promise<void>::Promise(bsls::SystemClockType::Enum clockType,
                              bslma::Allocator*           basicAllocator)
: Impl(clockType, basicAllocator)
{
    // NOTHING
}

inline Promise<void>::Promise(bslmf::MovableRef<Promise> original)
    BSLS_KEYWORD_NOEXCEPT
: Impl(bslmf::MovableRefUtil::move(
      static_cast<Impl&>(bslmf::MovableRefUtil::access(original))))
{
    // NOTHING
}

// MANIPULATORS
inline Promise<void>&
Promise<void>::operator=(bslmf::MovableRef<Promise> rhs) BSLS_KEYWORD_NOEXCEPT
{
    static_cast<Impl&>(*this) = bslmf::MovableRefUtil::move(
        static_cast<Impl&>(bslmf::MovableRefUtil::access(rhs)));
    return *this;
}

inline void Promise<void>::setValue()
{
    Impl::setValue(bslmf::Nil());
}

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_EXCEPTION_HANDLING
inline void Promise<void>::setException(bsl::exception_ptr exception)
{
    Impl::setException(exception);
}
#endif

template <class EXCEPTION>
inline void
Promise<void>::setException(BSLS_COMPILERFEATURES_FORWARD_REF(EXCEPTION)
                                exception)
{
    Impl::setException(BSLS_COMPILERFEATURES_FORWARD(EXCEPTION, exception));
}

inline void Promise<void>::swap(Promise& other) BSLS_KEYWORD_NOEXCEPT
{
    Impl::swap(other);
}

// ACCESSORS
inline Future<void> Promise<void>::future() const BSLS_KEYWORD_NOEXCEPT
{
    // PRECONDITIONS
    BSLS_ASSERT(this->d_sharedState);

    return Future<void>(this->d_sharedState);
}

// -----------------
// class Promise<R&>
// -----------------

// CREATORS
template <class R>
inline Promise<R&>::Promise(bslma::Allocator* basicAllocator)
: Impl(basicAllocator)
{
    // NOTHING
}

template <class R>
inline Promise<R&>::Promise(bsls::SystemClockType::Enum clockType,
                            bslma::Allocator*           basicAllocator)
: Impl(clockType, basicAllocator)
{
    // NOTHING
}

template <class R>
inline Promise<R&>::Promise(bslmf::MovableRef<Promise> original)
    BSLS_KEYWORD_NOEXCEPT
: Impl(bslmf::MovableRefUtil::move(
      static_cast<Impl&>(bslmf::MovableRefUtil::access(original))))
{
    // NOTHING
}

// MANIPULATORS
template <class R>
inline Promise<R&>&
Promise<R&>::operator=(bslmf::MovableRef<Promise> rhs) BSLS_KEYWORD_NOEXCEPT
{
    static_cast<Impl&>(*this) = bslmf::MovableRefUtil::move(
        static_cast<Impl&>(bslmf::MovableRefUtil::access(rhs)));
    return *this;
}

template <class R>
inline void Promise<R&>::setValue(R& value)
{
    Impl::setValue(bsl::ref(value));
}

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_EXCEPTION_HANDLING
template <class R>
inline void Promise<R&>::setException(bsl::exception_ptr exception)
{
    Impl::setException(exception);
}
#endif

template <class R>
template <class EXCEPTION>
inline void
Promise<R&>::setException(BSLS_COMPILERFEATURES_FORWARD_REF(EXCEPTION)
                              exception)
{
    Impl::setException(BSLS_COMPILERFEATURES_FORWARD(EXCEPTION, exception));
}

template <class R>
inline void Promise<R&>::swap(Promise& other) BSLS_KEYWORD_NOEXCEPT
{
    Impl::swap(other);
}

// ACCESSORS
template <class R>
inline Future<R&> Promise<R&>::future() const BSLS_KEYWORD_NOEXCEPT
{
    // PRECONDITIONS
    BSLS_ASSERT(this->d_sharedState);

    return Future<R&>(this->d_sharedState);
}

}  // close package namespace

// FREE OPERATORS
template <class R>
inline void mwcex::swap(Promise<R>& lhs, Promise<R>& rhs) BSLS_KEYWORD_NOEXCEPT
{
    lhs.swap(rhs);
}

}  // close enterprise namespace

#else  // if ! defined(DEFINED_MWCEX_PROMISE_H)
#error Not valid except when included from mwcex_promise.h
#endif  // ! defined(COMPILING_MWCEX_PROMISE_H)

#endif  // ! defined(INCLUDED_MWCEX_PROMISE_CPP03)

// ----------------------------------------------------------------------------
// Copyright 2022-2023 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
